package net.sf.calibur.engine;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

public class RecyclerBin implements Runnable {
	private LinkedBlockingQueue<Event> queue = new LinkedBlockingQueue<Event>();
	private CaliburEngine engine;
	private Thread thread;
	private Map<Class<?>, Recycler> recyclerMap = new ConcurrentHashMap<Class<?>, Recycler>();
	
	public RecyclerBin(CaliburEngine engine) {
		this.engine = engine;
	}
	
	public void addRecycler(Class<?> clazz, Recycler recycler) {
		recyclerMap.put(clazz, recycler);
	}
	
	public String getName() {
		return engine.getName() + "-recycler";
	}
	
	public void start() {
		thread = new Thread(this, getName());
		thread.start();
	}
	
	public void shutdown() {
		if (isRunning()) {
			queue.add(new ShutdownEvent());
		}
	}
	
	public boolean isRunning() {
		return thread == null ? false : thread.isAlive();
	}
	
	public void recycle(Event event) {
		queue.add(event);
	}
	
	@Override
	public void run() {
		Event event = null;
		Recycler recycler = null;
		
		while (true) {
			try {
				event = queue.take();
			} catch (InterruptedException ie) {
				return;
			}
	
			if (event instanceof ShutdownEvent) {
				return;
			}
			
			recycler = recyclerMap.get(event.getClass());
			if (recycler != null) {
				recycler.recycle(event);
			}
		}
		
	}
	
}
